﻿#region Using Statements
using System;
using System.Collections.Generic;

using Tunneler.Tools;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
#endregion

namespace Tunneler {

    enum GameState {
        MainMenu, Playing, Controls, Pregame
    }

    public class Game1 : Game {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        GameState gameState;

        bool gameInProgress;

        World world = World.Instance;
        ICollisionDetector collisionDetector;

        #region Border Variables
        Texture2D borderTexture;
        float borderScale;
        Vector2 borderPosition;
        float borderRotation;
        int borderOffset;
        #endregion

        Texture2D menuBackround;
        Cooldown switchCD;

        #region Main Menu Variables
        Texture2D resumeButton;
        Texture2D newGameButton;
        Texture2D controlsButton;
        Texture2D exitButton;

        bool mainMenuBoxesInit;
        Rectangle resumeBox;
        Rectangle newGameBox;
        Rectangle controlsBox;
        Rectangle exitBox;
        #endregion

        #region Pregame Menu Variables
        Texture2D startButton;
        Rectangle startBox;

        bool pregameBoxesInit;
        Rectangle smallMapBox;
        Rectangle mediumMapBox;
        Rectangle largeMapBox;
        int mapSize = 1;

        Rectangle smallArtBox;
        Rectangle mediumArtBox;
        Rectangle largeArtBox;
        int artCount = 1;

        Texture2D smallButton;
        Texture2D mediumButton;
        Texture2D largeButton;

        Texture2D lifeCountTexture;
        Rectangle lifeCountBox;
        Texture2D artCountTexture;
        Rectangle artCountBox;
        Texture2D mapSizeTexture;
        Rectangle mapSizeBox;

        Texture2D fewLivesButton;
        Rectangle fewLivesBox;
        Texture2D normalLivesButton;
        Rectangle normalLivesBox;
        Texture2D manyLivesButton;
        Rectangle manyLivesBox;
        int livesCount = 1;
        #endregion

        #region Controls Menu Variables
        bool controlsMenuBoxesInit;
        Texture2D playerSelButton;
        Rectangle playerSelBox;
        bool choosingBlue = true;

        Texture2D upSelButton;
        Rectangle upSelBox;
        Texture2D leftSelButton;
        Rectangle leftSelBox;
        Texture2D rightSelButton;
        Rectangle rightSelBox;
        Texture2D downSelButton;
        Rectangle downSelBox;
        Texture2D fireSelButton;
        Rectangle fireSelBox;

        int pressed;
        #endregion

        public const int SCREEN_WIDTH = 800;
        public const int SCREEN_HEIGHT = 600;

        // Players
        List<Player> players;
        List<PlayerBase> playerBases;
        List<PlayerInfo> playerInfos;
        Controls[] playerControls;

        // Cameras
        List<Camera> cameras;
        int cameraWidth;
        int cameraHeight = (int)((float)SCREEN_HEIGHT * 3f / 4f);

        // ViewPorts
        Viewport defaultViewPort;
        Viewport leftViewPort;
        Viewport rightViewPort;

        Random random = new Random();

        int ArtefactCount;

        public Game1()
            : base() {
            graphics = new GraphicsDeviceManager(this);
            graphics.IsFullScreen = false;
            graphics.PreferredBackBufferHeight = SCREEN_HEIGHT;
            graphics.PreferredBackBufferWidth = SCREEN_WIDTH;
            graphics.ApplyChanges();

            gameState = GameState.MainMenu;

            players = new List<Player>();
            playerBases = new List<PlayerBase>();
            playerInfos = new List<PlayerInfo>();
            playerControls = new Controls[2];

            this.Window.Title = "Tunneller";

            Content.RootDirectory = "Content";
        }

        protected override void Initialize() {
            base.Initialize();

            defaultViewPort = GraphicsDevice.Viewport;
            leftViewPort = defaultViewPort;
            rightViewPort = defaultViewPort;

            borderOffset = (int)((float)borderScale * (float)(borderTexture.Height / 2f));
            rightViewPort.Width = leftViewPort.Width = leftViewPort.Width / 2 - borderOffset;
            rightViewPort.X = leftViewPort.Width + borderOffset * 2;
            leftViewPort.Height = rightViewPort.Height = cameraHeight;

            cameras = new List<Camera>() { new Camera(world, borderOffset, SCREEN_HEIGHT- cameraHeight),
                new Camera(world, borderOffset, SCREEN_HEIGHT - cameraHeight) };
        }

        protected override void LoadContent() {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            collisionDetector = new CollisionDetector();

            world.Terrain = new Terrain(GraphicsDevice);
            world.Terrain.LoadContent(Content);

            cameraWidth = SCREEN_WIDTH / 2 - borderOffset;

            CreatePlayerInBase(PlayerType.Blue);
            CreatePlayerInBase(PlayerType.Red);
            CreatePlayerInfos();

            foreach (IGameObject obj in world.GameObjects) {
                obj.LoadContent(Content);
            }
            foreach (PlayerInfo pInfo in playerInfos) {
                pInfo.LoadContent(Content);
            }

            // User Interface
            borderTexture = Content.Load<Texture2D>("border");
            borderScale = (float)SCREEN_HEIGHT / (float)borderTexture.Width;
            borderPosition = new Vector2(SCREEN_WIDTH / 2 + borderTexture.Height * borderScale / 2, 0);
            borderRotation = (float)(Math.PI / 2);

            menuBackround = Content.Load<Texture2D>("menuBackground");
            resumeButton = Content.Load<Texture2D>("resume");
            newGameButton = Content.Load<Texture2D>("newGame");
            exitButton = Content.Load<Texture2D>("exit");
            controlsButton = Content.Load<Texture2D>("controls");

            smallButton = Content.Load<Texture2D>("small");
            mediumButton = Content.Load<Texture2D>("medium");
            largeButton = Content.Load<Texture2D>("large");
            startButton = Content.Load<Texture2D>("start");

            mapSizeTexture = Content.Load<Texture2D>("mapSize");
            artCountTexture = Content.Load<Texture2D>("artefactCount");
            lifeCountTexture = Content.Load<Texture2D>("lifeCount");

            playerSelButton = Content.Load<Texture2D>("playerSel");
            upSelButton = Content.Load<Texture2D>("Up");
            downSelButton = Content.Load<Texture2D>("Down");
            leftSelButton = Content.Load<Texture2D>("Left");
            rightSelButton = Content.Load<Texture2D>("Right");
            fireSelButton = Content.Load<Texture2D>("Fire");

            fewLivesButton = Content.Load<Texture2D>("3");
            normalLivesButton = Content.Load<Texture2D>("5");
            manyLivesButton = Content.Load<Texture2D>("7");
        }

        protected override void UnloadContent() {
        }

        protected override void Update(GameTime gameTime) {
            if (switchCD == null) {
                switchCD = new Cooldown(gameTime, 500);
            }

            switch (gameState) {
                case GameState.MainMenu:
                    Update_MainMenu(gameTime);
                    break;
                case GameState.Playing:
                    if (!gameInProgress) {
                        InitGame();
                    }
                    Update_Playing(gameTime);
                    break;
                case GameState.Pregame:
                    Update_Pregame(gameTime);
                    break;
                case GameState.Controls:
                    Update_Controls(gameTime);
                    break;
            }

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime) {
            switch (gameState) {
                case GameState.MainMenu:
                    Draw_MainMenu();
                    break;
                case GameState.Playing:
                    Draw_Playing(gameTime);
                    break;
                case GameState.Pregame:
                    Draw_Pregame();
                    break;
                case GameState.Controls:
                    Draw_Controls();
                    break;
            }
            base.Draw(gameTime);
        }

        private void Update_Playing(GameTime gameTime) {
            if (Keyboard.GetState().IsKeyDown(Keys.Escape)) {
                gameState = GameState.MainMenu;
                return;
            }
            IsMouseVisible = false;

            // Update all game objects
            for (int i = 0; i < world.GameObjects.Count; ++i) {
                world.GameObjects[i].Update(gameTime);
            }

            // Update Cameras
            for (int i = 0; i < cameras.Count; ++i) {
                cameras[i].Update(gameTime, players[i].Position);
            }

            // Chech for game object collisions
            collisionDetector.HandleCollidingObjects();

            // Check for terrain collisions
            collisionDetector.HandleTerrainCollisions();
        }

        private void InitGame() {
            gameInProgress = true;

            world.Terrain.Reset();

            Vector2 posBlue, posRed;
            GeneratedSpawnPositions(out posBlue, out posRed);
            players[0].SpawnPosition = playerBases[0].Position = posBlue;
            players[1].SpawnPosition = playerBases[1].Position = posRed;
            switch (livesCount) {
                case 0:
                    players[0].StartingLives = players[1].StartingLives = 3;
                    break;
                case 1:
                    players[0].StartingLives = players[1].StartingLives = 5;
                    break;
                case 2:
                    players[0].StartingLives = players[1].StartingLives = 7;
                    break;
            }


            world.Clear();
            for (int i = 0; i < 2; ++i) {
                world.RegisterGameObject(players[i]);
                world.RegisterGameObject(playerBases[i]);
            }
            GenerateArtefacts();
            foreach (Player p in players) {
                p.Reset();
            }
        }

        private void Update_MainMenu(GameTime gameTime) {
            IsMouseVisible = true;

            if (Mouse.GetState().LeftButton == ButtonState.Pressed) {
                var mousePos = Mouse.GetState().Position;
                if (gameInProgress && resumeBox.Contains(mousePos)) {
                    gameState = GameState.Playing;
                } else if (newGameBox.Contains(mousePos)) {
                    gameState = GameState.Pregame;
                } else if (exitBox.Contains(mousePos)) {
                    Exit();
                } else if (controlsBox.Contains(mousePos)) {
                    gameState = GameState.Controls;
                    pressed = -1;
                    switchCD.Use();
                }
            }
        }

        private void Update_Pregame(GameTime gameTime) {
            IsMouseVisible = true;

            if (Keyboard.GetState().IsKeyDown(Keys.Escape)) {
                gameState = GameState.MainMenu;
                return;
            }

            if (Mouse.GetState().LeftButton == ButtonState.Pressed) {
                var mousePos = Mouse.GetState().Position;
                if (smallMapBox.Contains(mousePos)) {
                    mapSize = 0;
                } else if (mediumMapBox.Contains(mousePos)) {
                    mapSize = 1;
                } else if (largeMapBox.Contains(mousePos)) {
                    mapSize = 2;
                }
                if (smallArtBox.Contains(mousePos)) {
                    artCount = 0;
                } else if (mediumArtBox.Contains(mousePos)) {
                    artCount = 1;
                } else if (largeArtBox.Contains(mousePos)) {
                    artCount = 2;
                }
                if (fewLivesBox.Contains(mousePos)) {
                    livesCount = 0;
                } else if (normalLivesBox.Contains(mousePos)) {
                    livesCount = 1;
                } else if (manyLivesBox.Contains(mousePos)) {
                    livesCount = 2;
                }
                if (startBox.Contains(mousePos)) {
                    gameInProgress = false;
                    gameState = GameState.Playing;
                    Terrain.SetSizeLevel(mapSize);
                    switch (artCount) {
                        case 0:
                            ArtefactCount = 3;
                            break;
                        case 1:
                            ArtefactCount = 5;
                            break;
                        case 2:
                            ArtefactCount = 10;
                            break;
                    }
                }
            }
        }

        private void Update_Controls(GameTime gameTime) {
            if (switchCD.IsHot()) {
                return;
            }
            if (Keyboard.GetState().IsKeyDown(Keys.Escape)) {
                gameState = GameState.MainMenu;
                return;
            }

            if (Mouse.GetState().LeftButton == ButtonState.Pressed) {
                var mousePos = Mouse.GetState().Position;
                if (playerSelBox.Contains(mousePos)) {
                    pressed = -1;
                    choosingBlue = !choosingBlue;
                    switchCD.Use();
                } else if (upSelBox.Contains(mousePos)) {
                    pressed = 0;
                } else if (downSelBox.Contains(mousePos)) {
                    pressed = 1;
                } else if (leftSelBox.Contains(mousePos)) {
                    pressed = 2;
                } else if (rightSelBox.Contains(mousePos)) {
                    pressed = 3;
                } else if (fireSelBox.Contains(mousePos)) {
                    pressed = 4;
                }
            }


            Keys[] pKeys = Keyboard.GetState().GetPressedKeys();
            if (pKeys.Length > 0) {
                if (pressed >= 0 && pressed <= 4) {
                    BindKey(pKeys[0], choosingBlue, pressed);
                    pressed = -1;
                }
            }
        }

        private void Draw_Playing(GameTime gameTime) {
            if (!gameInProgress) {
                return;
            }
            GraphicsDevice.Clear(Color.CornflowerBlue);

            GraphicsDevice.Viewport = leftViewPort;
            DrawScene(cameras[0]);
            GraphicsDevice.Viewport = rightViewPort;
            DrawScene(cameras[1]);

            GraphicsDevice.Viewport = defaultViewPort;
            spriteBatch.Begin();
            DrawBorder();
            DrawPlayerInfos();
            spriteBatch.End();
        }

        private void Draw_Controls() {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();
            // Draw Background
            Rectangle screenRectangle = new Rectangle(0, 0, GraphicsDevice.PresentationParameters.BackBufferWidth,
                GraphicsDevice.PresentationParameters.BackBufferHeight);
            spriteBatch.Draw(menuBackround, screenRectangle, Color.White);

            if (!controlsMenuBoxesInit) {
                controlsMenuBoxesInit = true;
                Vector2 buttonsPos = new Vector2(GraphicsDevice.PresentationParameters.BackBufferWidth / 3,
                    GraphicsDevice.PresentationParameters.BackBufferHeight / 8);

                int butWidth = playerSelButton.Width;
                int butHeight = playerSelButton.Height;

                playerSelBox = new Rectangle((int)buttonsPos.X, (int)(buttonsPos.Y), butWidth, butHeight);
                upSelBox = new Rectangle((int)buttonsPos.X, (int)(buttonsPos.Y + 1.2 * butHeight), butWidth, butHeight);
                leftSelBox = new Rectangle((int)(buttonsPos.X - 1.2 * butWidth), (int)(upSelBox.Top + 1.2 * butHeight), butWidth, butHeight);
                downSelBox = new Rectangle((int)(buttonsPos.X), (int)(upSelBox.Top + 1.2 * butHeight), butWidth, butHeight);
                rightSelBox = new Rectangle((int)(buttonsPos.X + 1.2 * butWidth), (int)(upSelBox.Top + 1.2 * butHeight), butWidth, butHeight);
                fireSelBox = new Rectangle((int)(buttonsPos.X), (int)(downSelBox.Top + 1.2 * butHeight), butWidth, butHeight);
            }

            // Draw Play Selector
            spriteBatch.Draw(playerSelButton, playerSelBox, choosingBlue ? Color.Blue : Color.Red);

            // Draw Control Buttons
            spriteBatch.Draw(upSelButton, upSelBox, pressed == 0 ? Color.Green : Color.White);
            spriteBatch.Draw(downSelButton, downSelBox, pressed == 1 ? Color.Green : Color.White);
            spriteBatch.Draw(leftSelButton, leftSelBox, pressed == 2 ? Color.Green : Color.White);
            spriteBatch.Draw(rightSelButton, rightSelBox, pressed == 3 ? Color.Green : Color.White);
            spriteBatch.Draw(fireSelButton, fireSelBox, pressed == 4 ? Color.Green : Color.White);

            spriteBatch.End();
        }

        private void Draw_MainMenu() {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();

            // Draw Background
            Rectangle screenRectangle = new Rectangle(0, 0, GraphicsDevice.PresentationParameters.BackBufferWidth,
                GraphicsDevice.PresentationParameters.BackBufferHeight);
            spriteBatch.Draw(menuBackround, screenRectangle, Color.White);

            if (!mainMenuBoxesInit) {
                mainMenuBoxesInit = true;
                Vector2 buttonsPos = new Vector2(GraphicsDevice.PresentationParameters.BackBufferWidth / 3,
                    GraphicsDevice.PresentationParameters.BackBufferHeight / 5);
                resumeBox = new Rectangle((int)buttonsPos.X, (int)buttonsPos.Y, exitButton.Width, exitButton.Height);
                newGameBox = new Rectangle((int)buttonsPos.X, (int)(buttonsPos.Y + exitButton.Height * 1.5), exitButton.Width, exitButton.Height);
                controlsBox = new Rectangle((int)buttonsPos.X, (int)(buttonsPos.Y + exitButton.Height * 3), exitButton.Width, exitButton.Height);
                exitBox = new Rectangle((int)buttonsPos.X, (int)(buttonsPos.Y + exitButton.Height * 4.5), exitButton.Width, exitButton.Height);
            }

            if (gameInProgress) {
                // Draw Resume Button
                spriteBatch.Draw(resumeButton, resumeBox, Color.White);
            }

            // Draw NewGame Button
            spriteBatch.Draw(newGameButton, newGameBox, Color.White);

            // Draw Controls Button
            spriteBatch.Draw(controlsButton, controlsBox, Color.White);

            // Draw Exit Button
            spriteBatch.Draw(exitButton, exitBox, Color.White);

            spriteBatch.End();
        }

        private void Draw_Pregame() {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();

            Rectangle screenRectangle = new Rectangle(0, 0, GraphicsDevice.PresentationParameters.BackBufferWidth,
                     GraphicsDevice.PresentationParameters.BackBufferHeight);
            spriteBatch.Draw(menuBackround, screenRectangle, Color.White);


            if (!pregameBoxesInit) {
                pregameBoxesInit = true;

                int butWidth = smallButton.Width;
                int butHeight = smallButton.Height;

                mapSizeBox = new Rectangle(GraphicsDevice.PresentationParameters.BackBufferWidth / 15,
                    GraphicsDevice.PresentationParameters.BackBufferHeight / 16,
                    butWidth, butHeight);

                Vector2 mapPos = new Vector2(mapSizeBox.Left,
                    (int)(mapSizeBox.Top + butHeight * 1.2));

                smallMapBox = new Rectangle((int)(mapPos.X), (int)(mapPos.Y), butWidth, butHeight);
                mediumMapBox = new Rectangle((int)(mapPos.X + butWidth * 1.2), (int)(mapPos.Y), butWidth, butHeight);
                largeMapBox = new Rectangle((int)(mapPos.X + butWidth * 1.2 * 2), (int)(mapPos.Y), butWidth, butHeight);

                artCountBox = new Rectangle(mapSizeBox.Left, (int)(mapSizeBox.Top + butHeight * 2 * 1.2), butWidth, butHeight);

                smallArtBox = new Rectangle((int)mapPos.X, (int)(artCountBox.Top + 1.2 * butHeight), butWidth, butHeight);
                mediumArtBox = new Rectangle((int)(mapPos.X + butWidth * 1.2), (int)(artCountBox.Top + 1.2 * butHeight), butWidth, butHeight);
                largeArtBox = new Rectangle((int)(mapPos.X + butWidth * 1.2 * 2), (int)(artCountBox.Top + 1.2 * butHeight), butWidth, butHeight);

                lifeCountBox = new Rectangle(mapSizeBox.Left, (int)(artCountBox.Top + butHeight * 2 * 1.2), butWidth, butHeight);

                fewLivesBox = new Rectangle((int)mapPos.X, (int)(lifeCountBox.Top + 1.2 * butHeight), butWidth, butHeight);
                normalLivesBox = new Rectangle((int)(mapPos.X + butWidth * 1.2), (int)(lifeCountBox.Top + 1.2 * butHeight), butWidth, butHeight);
                manyLivesBox = new Rectangle((int)(mapPos.X + butWidth * 1.2 * 2), (int)(lifeCountBox.Top + 1.2 * butHeight), butWidth, butHeight);
                startBox = new Rectangle((int)mapPos.X, GraphicsDevice.PresentationParameters.BackBufferHeight * 6 / 7, butWidth, butHeight);
            }

            // Draw Map Size Buttons
            spriteBatch.Draw(mapSizeTexture, mapSizeBox, Color.White);
            spriteBatch.Draw(smallButton, smallMapBox, mapSize == 0 ? Color.Red : Color.White);
            spriteBatch.Draw(mediumButton, mediumMapBox, mapSize == 1 ? Color.Red : Color.White);
            spriteBatch.Draw(largeButton, largeMapBox, mapSize == 2 ? Color.Red : Color.White);

            // Draw Artefact Count Buttons
            spriteBatch.Draw(artCountTexture, artCountBox, Color.White);
            spriteBatch.Draw(smallButton, smallArtBox, artCount == 0 ? Color.Red : Color.White);
            spriteBatch.Draw(mediumButton, mediumArtBox, artCount == 1 ? Color.Red : Color.White);
            spriteBatch.Draw(largeButton, largeArtBox, artCount == 2 ? Color.Red : Color.White);

            // Draw Life Count Buttons
            spriteBatch.Draw(lifeCountTexture, lifeCountBox, Color.White);
            spriteBatch.Draw(fewLivesButton, fewLivesBox, livesCount == 0 ? Color.Red : Color.White);
            spriteBatch.Draw(normalLivesButton, normalLivesBox, livesCount == 1 ? Color.Red : Color.White);
            spriteBatch.Draw(manyLivesButton, manyLivesBox, livesCount == 2 ? Color.Red : Color.White);

            // Draw Start Button
            spriteBatch.Draw(startButton, startBox, Color.White);

            spriteBatch.End();
        }

        private void DrawScene(Camera camera) {
            spriteBatch.Begin(SpriteSortMode.Deferred,
                BlendState.AlphaBlend,
                null, null, null, null,
                camera.Transform);

            // First we draw the terrain and then game objects on top of it.
            world.Terrain.Draw(spriteBatch);
            foreach (IGameObject obj in world.GameObjects) {
                obj.Draw(spriteBatch);
            }

            spriteBatch.End();
        }

        private void DrawBorder() {
            Vector2 origin = new Vector2(borderScale * borderTexture.Height / 2 - 5, 0);
            spriteBatch.Draw(borderTexture, borderPosition, null, Color.White, borderRotation, origin, borderScale, SpriteEffects.None, 0);
        }

        private void DrawPlayerInfos() {
            foreach (PlayerInfo playerInfo in playerInfos) {
                playerInfo.Draw(spriteBatch);
            }
        }

        private void BindKey(Keys key, bool blue, int controlIndex) {
            if (key == Keys.Escape || playerControls[0].UsedKey(key)
                || playerControls[1].UsedKey(key)) {
                pressed = -1;
                return;
            }
            Controls controls = playerControls[1];


            if (blue) {
                controls = playerControls[0];
            }

            switch (controlIndex) {
                case 0:
                    controls.SetUp(key);
                    break;
                case 1:
                    controls.SetDown(key);
                    break;
                case 2:
                    controls.SetLeft(key);
                    break;
                case 3:
                    controls.SetRight(key);
                    break;
                case 4:
                    controls.SetFire(key);
                    break;
            }
        }

        private void GeneratedSpawnPositions(out Vector2 posBlue, out Vector2 posRed) {
            const int minEdgeDistance = 200;
            const int minPlayerDistance = 500;

            int x = random.Next(minEdgeDistance, world.Terrain.Width - minEdgeDistance);
            int y = random.Next(minEdgeDistance, world.Terrain.Height - minEdgeDistance);

            posBlue = new Vector2(x, y);

            bool notDone = true;
            do {
                x = random.Next(minEdgeDistance, world.Terrain.Width - minEdgeDistance);
                y = random.Next(minEdgeDistance, world.Terrain.Height - minEdgeDistance);

                if (Math.Abs(posBlue.X - x) < minPlayerDistance || Math.Abs(posBlue.Y - y) < minPlayerDistance) {
                    continue;
                }
                if (x < minPlayerDistance || x > world.Terrain.Width - minEdgeDistance
                    || y < minEdgeDistance || y > world.Terrain.Height - minEdgeDistance) {
                    continue;
                }
                notDone = false;
            } while (notDone);
            posRed = new Vector2(x, y);
        }

        private void CreatePlayerInBase(PlayerType pType) {
            Controls pControls = new Controls();

            // Default Controls
            if (pType == PlayerType.Blue) {
                pControls.SetUp(Keys.W).SetDown(Keys.S).SetLeft(Keys.A).SetRight(Keys.D).SetFire(Keys.Space).SetGamepadIndex(PlayerIndex.One);
                playerControls[0] = pControls;
            } else {
                pControls.SetUp(Keys.Up).SetDown(Keys.Down).SetLeft(Keys.Left).SetRight(Keys.Right).SetFire(Keys.P).SetGamepadIndex(PlayerIndex.Two);
                playerControls[1] = pControls;
            }

            PlayerBase playerBase = new PlayerBase(graphics.GraphicsDevice, pType);
            Player player = new Player(pType, playerBase, pControls);
            players.Add(player);
            playerBases.Add(playerBase);
            world.RegisterGameObject(player);
            world.RegisterGameObject(playerBase);
        }

        private void CreatePlayerInfos() {
            // Create Player One Info
            Vector2 pos = new Vector2(0, cameraHeight);
            PlayerInfo pInfo = new PlayerInfo(players[0], pos, cameraWidth, SCREEN_HEIGHT - cameraHeight);
            playerInfos.Add(pInfo);


            // Create Player Two Info
            pos = new Vector2(SCREEN_WIDTH / 2 + borderOffset, cameraHeight);
            pInfo = new PlayerInfo(players[1], pos, cameraWidth, SCREEN_HEIGHT - cameraHeight);
            playerInfos.Add(pInfo);
        }

        private void GenerateArtefacts() {
            int cnt = 0;
            for (int i = 0; i < ArtefactCount; ++i) {
                Artefact a = new Artefact();
                a.LoadContent(Content);
                bool coliding;
                do {
                    cnt++;
                    int x = random.Next(200, world.Terrain.Width - 200);
                    int y = random.Next(200, world.Terrain.Width - 200);

                    coliding = false;
                    a.Position = new Vector2(x, y);

                    for (int j = 0; j < world.GameObjects.Count; ++j) {
                        if (collisionDetector.IntersectBounds(a, world.GameObjects[j])) {
                            coliding = true;
                            break;
                        }
                    }

                } while (coliding);
                world.RegisterGameObject(a);
            }
            cnt--;
        }
    }
}
